package cog.support.util.serializable.hashmap;

import cog.support.util.serializable.CogSerializable;
import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.beanutils.ConvertUtils;

import java.beans.BeanInfo;
import java.beans.IntrospectionException;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * HashMap方式的对象序列化
 *
 * @author 陈杰
 * @since 2016年9月12日 00:53:51
 * @version v0.1
 *
 * Copyright ChenJie(chenjie_java@aliyun.com) 2016年9月12日 00:53:51
 */
public class CogHashMapSerializable<T> implements CogSerializable<Map<String,T>> {

    private Class<?> tempClass;

    public CogHashMapSerializable(Class<?> tClass){
        this.tempClass = tClass;
    }

    @Override
    public Map<String, T> serializableToObject(Object inObject) {
        Map<String,T> returnMap = new HashMap<>();
        try {
            BeanInfo beanInfo = Introspector.getBeanInfo(inObject.getClass(),Object.class);
            PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors();
            for (PropertyDescriptor property : propertyDescriptors) {
                String key = property.getName();
                if (key.compareToIgnoreCase("class") == 0) {
                    continue;
                }
                Method getter = property.getReadMethod();
                Object value = getter!=null ? getter.invoke(inObject) : null;
                if(value != null)
                    returnMap.put(key, (T) ConvertUtils.convert(value,tempClass));
            }
        } catch (IntrospectionException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
        return returnMap;
    }

    private List<Field> getAllField(Class clasz){
        List<Field> list = new ArrayList<>();
        Class currentClass = clasz;
        while(!currentClass.getTypeName().equals("java.lang.Object")){
            Field[]  fileList = currentClass.getDeclaredFields();
            for(Field f : fileList){
                list.add(f);
            }
            currentClass = currentClass.getSuperclass();
        }
        return list;
    }

    @Override
    public <K> K serializableFromObject(Map<String,T> inMap , Class<?> clazs) {
        Object returnObject = null;
        if(inMap!=null){
            try {
                returnObject = clazs.newInstance();
                BeanUtils.copyProperties(returnObject,inMap);
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            } catch (InvocationTargetException e) {
                e.printStackTrace();
            } catch (InstantiationException e) {
                e.printStackTrace();
            }
        }
        return (K) returnObject;
    }
}
